package com.yonyou.distribute.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.yonyou.distribute.mapper.StockMapper;
import com.yonyou.distribute.pojo.Stock;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * p15、p16  乐观锁解决超卖
 * 时间戳或者版本号：底层依赖cas
 *
 * 缺点：
 * 1、性能低
 * 2、ABA问题
 */
@Slf4j
@Service
public class MysqlService_6 {

    @Resource
    private StockMapper stockMapper;

    @Value("${server.port}")
    private Integer port;

    /**
     * 更新数据库会锁定某条数据  ，spring的可以注释，不然会阻塞其他线程操作
     */
    @Transactional
    public void deduct() {

        // 1、查询库存
        List<Stock> stocks = this.stockMapper.selectList(new QueryWrapper<Stock>().eq("product_code", "1001"));
        Stock stock = stocks.get(0);
        int version = stock.getVersion();
        // 2、判断库存是否充足
        if(null != stock && stock.getCount() > 0){
            stock.setCount(stock.getCount() - 1);
            stock.setVersion(stock.getVersion() + 1);
            System.out.println("剩余库存：" + stock.getCount() + "--" + port);

            //3、更新库存到数据库
            if(this.stockMapper.update(stock, new UpdateWrapper<Stock>().eq("id", stock.getId()).eq("version", version)) == 0){
                // 如果更新失败，则重试
                try {
                    TimeUnit.MILLISECONDS.sleep(20);
                }catch (Exception e){
                    e.printStackTrace();
                }
                this.deduct();
            }
        }
    }
}
